package com.activities.group;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Map;

import android.app.Activity;
import android.app.ActivityGroup;
import android.app.AlertDialog;
import android.app.LocalActivityManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;

import com.Utility.UserTokenExpire;
import com.Utility.Utility;

/**
 * The purpose of this abstract Activity is to manage the activities in a tab.
 * Note: Child Activities can handle Key Presses before they are seen here.
 */
@SuppressWarnings("deprecation")
public class TabBaseGroupActivity extends ActivityGroup {

	/**
	 * Containing IDs of child activites.
	 */
	private UserTokenExpire mUserExpireTask;
	private ArrayList<String> mIdList;
	private String LOG_TAG = TabBaseGroupActivity.class.getSimpleName();

	/**
	 * This is called at first when an activity is created.
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (mIdList == null)
			mIdList = new ArrayList<String>();
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		// TODO Auto-generated method stub
		super.onConfigurationChanged(newConfig);
	}

	/**
	 * This is called when a child activity of this one calls its finish method.
	 * This implementation calls {@link LocalActivityManager#destroyActivity} on
	 * the child activity and starts the previous activity. If the last child
	 * activity just called finish(),this activity (the parent), calls finish to
	 * finish the entire group.
	 */
	@Override
	public void finishFromChild(Activity child) {
		try {
			LocalActivityManager manager = getLocalActivityManager();
			int index = mIdList.size() - 1;

			if (index < 1) {
				System.out.println("FINISH 1");
				finish();
				return;
			}
			String id = mIdList.get(index);
			customDestroy(id, manager);
			// Log.v("Bool",bool+"::");
			// manager.destroyActivity(id, true);
			mIdList.remove(index);
			index--;
			String lastId = mIdList.get(index);
			Intent lastIntent = manager.getActivity(lastId).getIntent();
			Window newWindow = manager.startActivity(lastId, lastIntent);
			setContentView(newWindow.getDecorView());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * To destroy child activity when tap on device' Back Button
	 * 
	 * @param id
	 * @param manager
	 * @return boolean
	 */
	private boolean customDestroy(String id, LocalActivityManager manager) {
		if (manager != null) {
			manager.destroyActivity(id, false);
			try {
				final Field mActivitiesField = LocalActivityManager.class
						.getDeclaredField("mActivities");

				if (mActivitiesField != null) {
					mActivitiesField.setAccessible(true);
					@SuppressWarnings("unchecked")
					final Map<String, Object> mActivities = (Map<String, Object>) mActivitiesField
							.get(manager);
					if (mActivities != null) {
						mActivities.remove(id);
					}
					final Field mActivityArrayField = LocalActivityManager.class
							.getDeclaredField("mActivityArray");
					if (mActivityArrayField != null) {
						mActivityArrayField.setAccessible(true);
						@SuppressWarnings("unchecked")
						final ArrayList<Object> mActivityArray = (ArrayList<Object>) mActivityArrayField
								.get(manager);
						if (mActivityArray != null) {
							for (Object record : mActivityArray) {
								final Field idField = record.getClass()
										.getDeclaredField("id");
								if (idField != null) {
									idField.setAccessible(true);
									final String _id = (String) idField
											.get(record);
									if (id.equals(_id)) {
										mActivityArray.remove(record);
										break;
									}
								}
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			return true;
		}
		return false;
	}

	/**
	 * Starts an Activity as a child Activity to this.
	 * 
	 * @param Id
	 *            Unique identifier of the activity to be started.
	 * @param intent
	 *            The Intent describing the activity to be started.
	 * @throws android.content.ActivityNotFoundException.
	 */
	public void startChildActivity(String Id, Intent intent) {
		Window window = getLocalActivityManager().startActivity(Id, intent);// .addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY));

		if (window != null) {
			View decorView = window.getDecorView();
			Log.v("decorView", decorView + "");
			mIdList.add(Id);
			setContentView(decorView);
		}
	}

	/**
	 * The primary purpose is to prevent systems before
	 * android.os.Build.VERSION_CODES.ECLAIR from calling their default
	 * KeyEvent.KEYCODE_BACK during onKeyDown.
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			// preventing default implementation previous to
			// android.os.Build.VERSION_CODES.ECLAIR
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	/**
	 * Overrides the default implementation for KeyEvent.KEYCODE_BACK so that
	 * all systems call onBackPressed().
	 */
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			onBackPressed();
			return true;
		}
		return super.onKeyUp(keyCode, event);
	}

	/**
	 * If a Child Activity handles KeyEvent.KEYCODE_BACK. Simply override and
	 * add this method.
	 */
	@Override
	public void onBackPressed() {
		Log.v(LOG_TAG, "onBackPressed");
		try {
			int length = mIdList.size();
			if (length > 0) {
				Activity current = getLocalActivityManager().getActivity(
						mIdList.get(length - 1));
				Log.v("current", current + "");
				current.finish();
			}
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Called when an activity you launched exits, giving you the requestCode
	 * you started it with, the resultCode it returned, and any additional data
	 * from it. The resultCode will be RESULT_CANCELED if the activity
	 * explicitly returned that, didn't return any result, or crashed during its
	 * operation.
	 * 
	 * You will receive this call immediately before onResume() when your
	 * activity is re-starting.
	 * 
	 * Parameters requestCode: The integer request code originally supplied to
	 * startActivityForResult(), allowing you to identify who this result came
	 * from. resultCode: The integer result code returned by the child activity
	 * through its setResult(). data: An Intent, which can return result data to
	 * the caller (various data can be attached to Intent "extras").
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		Log.v(TabBaseGroupActivity.class.getSimpleName() + ":req code:res code:: ",
				requestCode + "::" + resultCode);
	}

	/**
	 * Called when activity is destroyed to make free space
	 */
	@Override
	protected void onDestroy() {
		if (mUserExpireTask != null) {
			mUserExpireTask.cancel(true);
			mUserExpireTask = null;
		}
		super.onDestroy();
		// android.os.Debug.stopMethodTracing();
	}

	public void clearOnTop() {
		if (mIdList == null)
			return;
		while (mIdList.size() > 1) {
			Activity current = getLocalActivityManager().getActivity(
					mIdList.get(mIdList.size() - 1));
			current.finish();
		}
	}

	public void onLogout(View v) {
		AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
		builder.setMessage("Do you want to logout?")
				.setCancelable(false)
				.setPositiveButton("Yes",
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								dialog.dismiss();
								if (mUserExpireTask != null) {
									mUserExpireTask.cancel(true);
									mUserExpireTask = null;
								}
								mUserExpireTask = new UserTokenExpire(
										TabBaseGroupActivity.this);
								mUserExpireTask.execute(Utility
										.getStringPreference(
												TabBaseGroupActivity.this,
												Utility.KEY_PASSWORD, "#"));
							}
						})
				.setNegativeButton("No", new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						// put your code here
						dialog.cancel();
					}
				});
		AlertDialog alertDialog = builder.create();
		alertDialog.show();
	}
}
